package jnpf.engine.custom.type;


import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jnpf.base.UserInfo;
import jnpf.engine.assembly.UserTaskExPropertyDTO;
import jnpf.engine.entity.FlowTaskOperatorEntity;
import jnpf.engine.entity.FlowTaskOperatorRecordEntity;
import jnpf.engine.enums.FlowNodeEnum;
import jnpf.engine.enums.FlowRecordEnum;
import jnpf.engine.enums.FlowTaskOperatorEnum;
import jnpf.engine.service.FlowTaskOperatorRecordService;
import jnpf.engine.service.FlowTaskOperatorService;
import jnpf.engine.util.ActivitiNativeTaskQueryUtils;
import jnpf.engine.util.BpmnModelUtils;
import jnpf.engine.util.SpringContextHolder;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
import org.flowable.common.engine.impl.event.FlowableEntityEventImpl;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.TaskService;
import org.flowable.task.service.delegate.DelegateTask;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

import static jnpf.engine.custom.constants.GlobalProcessVariableConstants.CALL_ACTIVITY_AUTO_COMPLETE_FIRST_NODE;
import static jnpf.engine.util.BpmnModelUtils.getAttributeValueByTaskDefinitionKey;
import static jnpf.engine.custom.constants.GlobalProcessVariableConstants.CALL_ACTIVITY_FLAG;

@Component
@Slf4j
public class FirstActivityAutoCompleteListener implements FlowableEventListener {
    @Override
    public void onEvent(FlowableEvent activitiEvent) {
        if (!(activitiEvent instanceof FlowableEntityEventImpl)) {
            return;
        }

        FlowableEntityEventImpl activitiEntityEventImpl = (FlowableEntityEventImpl) activitiEvent;
        Object entity = activitiEntityEventImpl.getEntity();

        if (!(entity instanceof TaskEntity)) {
            return;
        }

        TaskEntity taskEntity = (TaskEntity) entity;
        Object variable = taskEntity.getVariable(CALL_ACTIVITY_FLAG);

        if(variable==null){
            return;
        }
        try {
            Boolean autoSubmitFlag = (Boolean) taskEntity.getVariable(CALL_ACTIVITY_AUTO_COMPLETE_FIRST_NODE);
            if(autoSubmitFlag){
                //如果是流程的第一步，则自动提交
                this.onCreate(taskEntity);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }
    /**
     * 如果失败 抛异常 即可回滚事务
     * @return
     */
    @Override
    public boolean isFailOnException() {
        return true;
    }

    @Override
    public boolean isFireOnTransactionLifecycleEvent() {
        return false;
    }

    @Override
    public String getOnTransaction() {
        return null;
    }

    private void onCreate(DelegateTask delegateTask) throws Exception {
        //如果是流程的第一步，则自动提交
        UserTask userTask = findFirstActivity(delegateTask.getProcessDefinitionId());
        if (!userTask.getId().equals(delegateTask.getTaskDefinitionKey())) {
            return;
        }
        //判断是否存在历史节点,存在说明第一个节点已经自动审批过
        //判断是不是第一次进入该节点, 如果不是则肯定是驳回回来的,那么 驳回回来的是需要发站内信的,
        ActivitiNativeTaskQueryUtils activitiNativeTaskQueryUtils = SpringContextHolder.getBean(ActivitiNativeTaskQueryUtils.class);
        Long count = activitiNativeTaskQueryUtils.firstActivityFlag(delegateTask.getTaskDefinitionKey(), delegateTask.getProcessInstanceId());
        //说明是第二次进入
        if(count>1) {
            return;
        }
        else{
            TaskService taskService = SpringContextHolder.getBean(TaskService.class);
            UserProvider userProvider = SpringContextHolder.getBean(UserProvider.class);
            FlowTaskOperatorService flowTaskOperatorService = SpringContextHolder.getBean(FlowTaskOperatorService.class);
            RepositoryService repositoryService = SpringContextHolder.getBean(RepositoryService.class);
            FlowTaskOperatorRecordService flowTaskOperatorRecordService = SpringContextHolder.getBean(FlowTaskOperatorRecordService.class);
//            UserInfo userInfo = userProvider.get();
            taskService.complete(delegateTask.getId());
            String assignee = delegateTask.getAssignee();
            QueryWrapper<FlowTaskOperatorEntity> queryWrapper=new QueryWrapper<>();
            queryWrapper.lambda().eq(FlowTaskOperatorEntity::getTaskNodeId,delegateTask.getId())
                    .eq(FlowTaskOperatorEntity::getTaskId,delegateTask.getProcessInstanceId())
                    .eq(FlowTaskOperatorEntity::getHandleId, assignee)
                    .orderByAsc(FlowTaskOperatorEntity::getCreatorTime);
            List<FlowTaskOperatorEntity> list = flowTaskOperatorService.list(queryWrapper);
            FlowTaskOperatorEntity flowTaskOperatorEntity = list.get(0);
            //提交记录
            FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = new FlowTaskOperatorRecordEntity();
            flowTaskOperatorRecordEntity.setHandleOpinion("自动通过");
            flowTaskOperatorRecordEntity.setHandleId(assignee);
//            flowTaskOperatorRecordEntity.setHandleName(userInfo.getUserName());
            flowTaskOperatorRecordEntity.setHandleTime(new Date());
            flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.submit.getCode());
            flowTaskOperatorRecordEntity.setOperatorId(assignee);
            flowTaskOperatorRecordEntity.setNodeCode(delegateTask.getTaskDefinitionKey());
            flowTaskOperatorRecordEntity.setNodeName("开始");
            flowTaskOperatorRecordEntity.setTaskOperatorId(flowTaskOperatorEntity.getId());
            flowTaskOperatorRecordEntity.setTaskNodeId(delegateTask.getId());
            flowTaskOperatorRecordEntity.setTaskId(delegateTask.getProcessInstanceId());
            BpmnModel bpmnModel = repositoryService.getBpmnModel(delegateTask.getProcessDefinitionId());
            flowTaskOperatorRecordEntity.setStatus(0);
            flowTaskOperatorRecordService.create(flowTaskOperatorRecordEntity);

        }

    }

    /**
     * 找到第一个节点
     * @param processDefinitionId
     * @return
     */
    private UserTask findFirstActivity(String processDefinitionId) {
        Process process = BpmnModelUtils.getBpmnModelMainProcess(processDefinitionId);
        StartEvent startEvent = (StartEvent) process.getInitialFlowElement();
        FlowElement targetFlowElement = startEvent.getOutgoingFlows().get(0).getTargetFlowElement();
        if(targetFlowElement instanceof UserTask){
            return (UserTask)targetFlowElement;
        }
        else{
            return null;
        }
    }

    public RepositoryService getRepositoryService(){
        return SpringContextHolder.getBean(RepositoryService.class);
    }
}
